package org.sofun.subscription.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sofun.subscription.enums.DayType;
import org.sofun.subscription.enums.OffsetType;
import org.sofun.subscription.enums.OpenDayOrder;
import org.sofun.subscription.enums.TradeFrequency;
import org.sofun.subscription.model.SubscriptionRule;
import org.sofun.subscription.service.SubscriptionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * Bug修复演示类 - 过期开放日自动过滤
 */
@Component
public class BugFixDemo {
    
    private static final Logger logger = LoggerFactory.getLogger(BugFixDemo.class);
    
    @Autowired
    private SubscriptionService subscriptionService;
    
    /**
     * 演示bug修复前后的行为对比
     */
    public void demonstrateBugFix() {
        logger.info("=== Bug修复演示：过期开放日自动过滤 ===");
        
        // 构建测试规则
        SubscriptionRule rule = createTestRule();
        
        // 当前日期
        LocalDate today = LocalDate.now();
        logger.info("当前日期: {}", today);
        
        // 测试场景1：开始日期为过去，结束日期为未来
        demonstrateScenario1(rule, today);
        
        // 测试场景2：开始日期为当前月份的第一天
        demonstrateScenario2(rule, today);
        
        // 测试场景3：开始日期为未来
        demonstrateScenario3(rule, today);
    }
    
    /**
     * 场景1：开始日期为过去，结束日期为未来
     */
    private void demonstrateScenario1(SubscriptionRule rule, LocalDate today) {
        logger.info("\n--- 场景1：开始日期为过去，结束日期为未来 ---");
        
        LocalDate startDate = today.minusMonths(3); // 3个月前
        LocalDate endDate = today.plusMonths(6);    // 6个月后
        
        logger.info("开始日期: {} ({}个月前)", startDate, 3);
        logger.info("结束日期: {} ({}个月后)", endDate, 6);
        
        List<LocalDate> openDays = subscriptionService.generateOpenDaysWithExceptionHandling(
            rule, startDate, endDate, null);
        
        logger.info("生成的开放日数量: {}", openDays.size());
        logOpenDaysAnalysis(openDays, today);
    }
    
    /**
     * 场景2：开始日期为当前月份的第一天
     */
    private void demonstrateScenario2(SubscriptionRule rule, LocalDate today) {
        logger.info("\n--- 场景2：开始日期为当前月份的第一天 ---");
        
        LocalDate startDate = today.withDayOfMonth(1); // 当月第一天
        LocalDate endDate = today.plusMonths(3);       // 3个月后
        
        logger.info("开始日期: {} (当月第一天)", startDate);
        logger.info("结束日期: {} ({}个月后)", endDate, 3);
        
        List<LocalDate> openDays = subscriptionService.generateOpenDaysWithExceptionHandling(
            rule, startDate, endDate, null);
        
        logger.info("生成的开放日数量: {}", openDays.size());
        logOpenDaysAnalysis(openDays, today);
    }
    
    /**
     * 场景3：开始日期为未来
     */
    private void demonstrateScenario3(SubscriptionRule rule, LocalDate today) {
        logger.info("\n--- 场景3：开始日期为未来 ---");
        
        LocalDate startDate = today.plusMonths(1); // 1个月后
        LocalDate endDate = today.plusMonths(6);   // 6个月后
        
        logger.info("开始日期: {} ({}个月后)", startDate, 1);
        logger.info("结束日期: {} ({}个月后)", endDate, 6);
        
        List<LocalDate> openDays = subscriptionService.generateOpenDaysWithExceptionHandling(
            rule, startDate, endDate, null);
        
        logger.info("生成的开放日数量: {}", openDays.size());
        logOpenDaysAnalysis(openDays, today);
    }
    
    /**
     * 分析并记录开放日信息
     */
    private void logOpenDaysAnalysis(List<LocalDate> openDays, LocalDate today) {
        if (openDays.isEmpty()) {
            logger.info("没有生成任何开放日");
            return;
        }
        
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd (E)");
        
        // 统计过去、今天、未来的日期
        long pastCount = openDays.stream().mapToLong(date -> date.isBefore(today) ? 1 : 0).sum();
        long todayCount = openDays.stream().mapToLong(date -> date.isEqual(today) ? 1 : 0).sum();
        long futureCount = openDays.stream().mapToLong(date -> date.isAfter(today) ? 1 : 0).sum();
        
        logger.info("开放日分析:");
        logger.info("  - 过去的日期: {} 个", pastCount);
        logger.info("  - 今天的日期: {} 个", todayCount);
        logger.info("  - 未来的日期: {} 个", futureCount);
        
        // 显示前几个开放日
        int displayCount = Math.min(5, openDays.size());
        logger.info("前{}个开放日:", displayCount);
        for (int i = 0; i < displayCount; i++) {
            LocalDate openDay = openDays.get(i);
            String status = openDay.isAfter(today) ? "有效" : 
                           openDay.isEqual(today) ? "今天" : "已过期";
            logger.info("  {}. {} [{}]", i + 1, openDay.format(formatter), status);
        }
        
        if (openDays.size() > displayCount) {
            logger.info("  ... 还有{}个开放日", openDays.size() - displayCount);
        }
        
        // 验证修复效果
        boolean allValid = openDays.stream().allMatch(date -> date.isAfter(today));
        if (allValid) {
            logger.info("✅ 修复验证成功：所有开放日都是未来有效日期");
        } else {
            logger.warn("❌ 修复验证失败：仍包含过期日期");
        }
    }
    
    /**
     * 创建测试规则
     */
    private SubscriptionRule createTestRule() {
        SubscriptionRule rule = new SubscriptionRule();
        rule.setTradeFrequency(TradeFrequency.MONTHLY);
        rule.setOpenDayOrder(OpenDayOrder.POSITIVE);
        rule.setOpenDayIndex(1); // 每月第1天
        rule.setOpenDayType(DayType.NATURAL_DAY);
        rule.setCloseDayOffset(3);
        rule.setOffsetType(OffsetType.NATURAL_DAY);
        rule.setCutoffTime(LocalTime.of(14, 0));
        rule.setInitialDateTime(LocalDateTime.of(2024, 1, 1, 14, 0));
        
        logger.info("测试规则: 月度申购，每月正数第1个自然日");
        return rule;
    }
    
    /**
     * 演示不同规则下的修复效果
     */
    public void demonstrateDifferentRules() {
        logger.info("\n=== 不同规则下的修复效果演示 ===");
        
        LocalDate today = LocalDate.now();
        LocalDate startDate = today.minusMonths(2);
        LocalDate endDate = today.plusMonths(4);
        
        // 规则1：月度，正数第1天
        demonstrateRule("月度，正数第1天", TradeFrequency.MONTHLY, OpenDayOrder.POSITIVE, 1, 
                       startDate, endDate, today);
        
        // 规则2：月度，正数第15天
        demonstrateRule("月度，正数第15天", TradeFrequency.MONTHLY, OpenDayOrder.POSITIVE, 15, 
                       startDate, endDate, today);
        
        // 规则3：季度，倒数第1天
        demonstrateRule("季度，倒数第1天", TradeFrequency.QUARTERLY, OpenDayOrder.NEGATIVE, 1, 
                       startDate, endDate, today);
    }
    
    private void demonstrateRule(String ruleName, TradeFrequency frequency, OpenDayOrder order, 
                                int index, LocalDate startDate, LocalDate endDate, LocalDate today) {
        logger.info("\n--- {} ---", ruleName);
        
        SubscriptionRule rule = new SubscriptionRule();
        rule.setTradeFrequency(frequency);
        rule.setOpenDayOrder(order);
        rule.setOpenDayIndex(index);
        rule.setOpenDayType(DayType.NATURAL_DAY);
        rule.setCloseDayOffset(3);
        rule.setOffsetType(OffsetType.NATURAL_DAY);
        rule.setCutoffTime(LocalTime.of(14, 0));
        rule.setInitialDateTime(LocalDateTime.of(2024, 1, 1, 14, 0));
        
        List<LocalDate> openDays = subscriptionService.generateOpenDaysWithExceptionHandling(
            rule, startDate, endDate, null);
        
        logger.info("生成的开放日数量: {}", openDays.size());
        
        if (!openDays.isEmpty()) {
            boolean allValid = openDays.stream().allMatch(date -> date.isAfter(today));
            logger.info("修复效果: {}", allValid ? "✅ 所有日期都有效" : "❌ 仍有过期日期");
            
            logger.info("最近的开放日: {}", openDays.get(0));
            if (openDays.size() > 1) {
                logger.info("最远的开放日: {}", openDays.get(openDays.size() - 1));
            }
        }
    }
}
